package xyz.noark.codec.simple;

import com.alibaba.fastjson2.JSONB;
import com.alibaba.fastjson2.JSONFactory;
import com.alibaba.fastjson2.JSONWriter;
import org.apache.fury.Fury;
import org.apache.fury.config.Language;
import org.apache.fury.logging.LoggerFactory;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import xyz.noark.codec.simple.data.SimpleData;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 简单数据结构体序列化压测
 *
 * @author 小流氓[176543888@qq.com]
 */
@Fork(1)
@Warmup(iterations = 10, time = 1)
@Measurement(iterations = 10, time = 1)
@OutputTimeUnit(TimeUnit.SECONDS)
@BenchmarkMode({Mode.Throughput})
@State(Scope.Benchmark)
public class SimpleDataSerializeBenchmark {
    private SimpleData data;

    private Fury fury;
    private Fury furyX;


    @Setup
    public void init() throws IOException {
        this.data = SimpleDataTest.data;

        JSONFactory.setDisableAutoType(true);
        JSONFactory.setDisableReferenceDetect(true);

        fury = Fury.builder().withLanguage(Language.JAVA)
                .withRefTracking(false).requireClassRegistration(false).build();


        // String size = RamUsageEstimator.humanReadableUnits(RamUsageEstimator.sizeOf(skillFire_s2C_msg));
    }

    @Benchmark
    public byte[] furySerialize() {
        return fury.serialize(data);
    }

    @Benchmark
    public byte[] jsonbSerialize() {
        return JSONB.toBytes(data);
    }


    @Benchmark
    public byte[] staticJavaCode() throws IOException {
        return SimpleDataTest.encode(data);
    }

    public static void main(String[] args) throws RunnerException {
        LoggerFactory.disableLogging();
        Options opt = new OptionsBuilder()
                .include(SimpleDataSerializeBenchmark.class.getSimpleName()).result("result.json")
                .resultFormat(ResultFormatType.JSON)
                //      .addProfiler(GCProfiler.class)
//                .addProfiler(CompilerProfiler.class)
//                .verbosity(VerboseMode.EXTRA)
                // .addProfiler(JavaFlightRecorderProfiler.class)
                .build();
        new Runner(opt).run();
    }
}
